package com.joolun.activity.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joolun.activity.domain.ActivityAwardInfo;
import com.joolun.activity.domain.ActivityInfo;
import com.joolun.activity.domain.ActivityTakeInfo;
import com.joolun.activity.mapper.ActivityAwardInfoMapper;
import com.joolun.activity.service.IActivityAwardInfoService;
import com.joolun.activity.service.IActivityInfoService;
import com.joolun.activity.service.IActivityTakeInfoService;
import com.joolun.activity.vo.DrawAwardVo;
import com.joolun.common.utils.DateUtils;
import com.joolun.common.utils.GeneratorUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.joolun.activity.mapper.ActivityAwardMapper;
import com.joolun.activity.domain.ActivityAward;
import com.joolun.activity.service.IActivityAwardService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 活动奖品Service业务层处理
 *
 * @author www.joolun.com
 * @date 2022-11-22
 */
@Service
public class ActivityAwardServiceImpl extends ServiceImpl<ActivityAwardMapper, ActivityAward> implements IActivityAwardService
{
    @Autowired
    private ActivityAwardMapper activityAwardMapper;
    @Autowired
    private IActivityAwardInfoService iActivityAwardInfoService;
    @Autowired
    private IActivityTakeInfoService iActivityTakeInfoService;
    @Autowired
    private IActivityInfoService iActivityInfoService;

    /**
     * 查询活动奖品
     *
     * @param id 活动奖品ID
     * @return 活动奖品
     */
    @Override
    public ActivityAward selectActivityAwardById(String id)
    {
        return activityAwardMapper.selectActivityAwardById(id);
    }

    /**
     * 查询活动奖品列表
     *
     * @param activityAward 活动奖品
     * @return 活动奖品
     */
    @Override
    public List<ActivityAward> selectActivityAwardList(ActivityAward activityAward)
    {
        return activityAwardMapper.selectActivityAwardList(activityAward);
    }

    /**
     * 新增活动奖品
     *
     * @param activityAward 活动奖品
     * @return 结果
     */
    @Override
    @Transactional
    public int insertActivityAward(ActivityAward activityAward)
    {
        if(activityAward.getAwardNum()<=0){
            throw new RuntimeException("奖品数量小于1");
        }
        activityAward.setAwardCode(GeneratorUtils.getSecurityCode(6, GeneratorUtils.SecurityCodeLevel.Hard,false).toUpperCase());
        activityAward.setStatus("1");
        activityAward.setDelFlag("0");
        activityAward.setCreateTime(DateUtils.getNowDate());
        List<ActivityAwardInfo> activityAwardInfos=new ArrayList<>();
        for(int i=0;i<activityAward.getAwardNum();i++){
            ActivityAwardInfo activityAwardInfo=new ActivityAwardInfo();
            activityAwardInfo.setActivityCode(activityAward.getActivityCode());
            activityAwardInfo.setAwardCode(activityAward.getAwardCode());
            activityAwardInfo.setAwardInfoCode(activityAwardInfo.getAwardCode()+GeneratorUtils.getSecurityCode(4, GeneratorUtils.SecurityCodeLevel.Hard,false).toUpperCase());
            activityAwardInfo.setStatus("1");
            activityAwardInfo.setName(activityAward.getName());
            activityAwardInfos.add(activityAwardInfo);
        }
        iActivityAwardInfoService.saveBatch(activityAwardInfos);
        save(activityAward);
        return activityAwardInfos.size();
    }

    /**
     * 修改活动奖品
     *
     * @param activityAward 活动奖品
     * @return 结果
     */
    @Override
    public int updateActivityAward(ActivityAward activityAward)
    {
        return activityAwardMapper.updateActivityAward(activityAward);
    }

    /**
     * 批量删除活动奖品
     *
     * @param ids 需要删除的活动奖品ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteActivityAwardByIds(String[] ids)
    {
        //查询奖品状态
        ActivityAward activityAward=getById(ids[0]);
        if("2".equals(activityAward.getStatus())){
            throw new RuntimeException("已开奖不能删除");
        }
        //删除奖品明细
        iActivityAwardInfoService.remove(new QueryWrapper<ActivityAwardInfo>()
                .eq("activity_code",activityAward.getActivityCode())
                .eq("award_code",activityAward.getAwardCode()));
        //删除总奖品
        activityAwardMapper.deleteActivityAwardByIds(ids);
        return 1;
    }

    /**
     * 删除活动奖品信息
     *
     * @param id 活动奖品ID
     * @return 结果
     */
    @Override
    public int deleteActivityAwardById(String id)
    {
        return activityAwardMapper.deleteActivityAwardById(id);
    }

    @Override
    @Transactional
    public List<ActivityTakeInfo> drawAward(DrawAwardVo drawAwardVo) {

        Integer levelInt=1;

        //判断奖品是否开奖
        ActivityAward activityAward= getOne(new QueryWrapper<ActivityAward>()
                .eq("award_code",drawAwardVo.getAwardCode()));
        if("2".equals(activityAward.getStatus())){
            throw new RuntimeException("已开过奖不能重复开奖");
        }
        //判断活动是否开启
        ActivityInfo activityInfo=  iActivityInfoService.getOne(new QueryWrapper<ActivityInfo>()
                .eq("activity_code",activityAward.getActivityCode()));
        if("1".equals(activityInfo)){
            throw new RuntimeException("活动未开始");
        }
        if("3".equals(activityInfo)){
            throw new RuntimeException("活动已结束");
        }
       activityAward.setStatus("2");
       activityAward.setOpenTime(DateUtils.getNowDate());
        //查询奖品明细
       List<ActivityAwardInfo> activityAwardInfos= iActivityAwardInfoService.list(new QueryWrapper<ActivityAwardInfo>()
                .eq("award_code",drawAwardVo.getAwardCode()));

       List<ActivityTakeInfo> activityTakeInfos=new ArrayList<>();
       if(levelInt.equals(activityAward.getLevel())){
           //查询参与活动未中奖的人员数大于5
           List<ActivityTakeInfo> takeInfos= iActivityTakeInfoService.getTaskCodeStatus();
           activityTakeInfos= iActivityTakeInfoService.list(new QueryWrapper<ActivityTakeInfo>()
                   .eq("status","2")
                   .eq("activity_code",activityAward.getActivityCode())
                   .in("take_code",takeInfos.stream().map(ActivityTakeInfo::getTakeCode).collect(Collectors.toList())));
       }else{
           //查询参与活动未中奖的人员
           activityTakeInfos= iActivityTakeInfoService.list(new QueryWrapper<ActivityTakeInfo>()
                   .eq("status","2")
                   .eq("activity_code",activityAward.getActivityCode()));
       }
       //中奖人员
        List<ActivityTakeInfo> activityTakeInfoList=new ArrayList<>();
       if(activityAward.getAwardNum()>activityTakeInfos.size()){
           //当前奖品人数大于活动参与人数
           for(int i=0;i< activityTakeInfos.size();i++){
               //每个人都中奖
               ActivityTakeInfo  activityTakeInfo =activityTakeInfos.get(i);
               activityTakeInfo.setStatus("3");
               activityTakeInfoList.add(activityTakeInfo);
               //处理中奖的奖品明细
               ActivityAwardInfo activityAwardInfo= activityAwardInfos.get(i);
               activityAwardInfo.setStatus("2");
               if(null!=activityTakeInfo.getOpenId()){
                   activityAwardInfo.setOpenId(activityTakeInfo.getOpenId());
               }
               activityAwardInfo.setActivityTakeCode(activityTakeInfo.getActivityTakeCode());
               activityAwardInfo.setTakeTime(DateUtils.getNowDate());
               activityAwardInfo.setUserName(activityTakeInfo.getName());
               activityAwardInfo.setPhone(activityTakeInfo.getPhone());
               activityAwardInfo.setGenUserId(activityTakeInfo.getGenUserId());
               activityAwardInfo.setGenUser(activityTakeInfo.getGenUser());
               activityAwardInfo.setGenDept(activityTakeInfo.getGenDept());
               activityAwardInfo.setGenDeptId(activityTakeInfo.getGenDeptId());
               activityAwardInfos.set(i,activityAwardInfo);
           }
           //处理奖品总信息状态
           saveOrUpdate(activityAward);
           //更改奖品明细和活动参与明细表
           iActivityAwardInfoService.saveOrUpdateBatch(activityAwardInfos);
           iActivityTakeInfoService.saveOrUpdateBatch(activityTakeInfoList);
           return activityTakeInfoList;
       }else{
           //当前奖品人数小于等于活动参与人数
           //随机对象
           Random random = new Random();
           int size = activityTakeInfos.size();
           Set<ActivityTakeInfo> totals = new HashSet<ActivityTakeInfo>();
           ArrayList<ActivityTakeInfo> resultList = new ArrayList<>();
           while (totals.size() < activityAward.getAwardNum()) {//获取3个
               //随机再集合里取出元素，添加到新哈希集合
               totals.add(activityTakeInfos.get(random.nextInt(size)));
           }
           Iterator iterator = totals.iterator();
           while (iterator.hasNext()) {
               ActivityTakeInfo activityTakeInfo = (ActivityTakeInfo) iterator.next();
               resultList.add(activityTakeInfo);
           }
           for(int i=0;i< resultList.size();i++){
               //每个人都中奖
               ActivityTakeInfo  activityTakeInfo =resultList.get(i);
               activityTakeInfo.setStatus("3");
               activityTakeInfoList.add(activityTakeInfo);
               //处理中奖的奖品明细
               ActivityAwardInfo activityAwardInfo= activityAwardInfos.get(i);
               activityAwardInfo.setStatus("2");
               if(null!=activityTakeInfo.getOpenId()){
                   activityAwardInfo.setOpenId(activityTakeInfo.getOpenId());
               }
               activityAwardInfo.setActivityTakeCode(activityTakeInfo.getActivityTakeCode());
               activityAwardInfo.setTakeTime(DateUtils.getNowDate());
               activityAwardInfo.setUserName(activityTakeInfo.getName());
               activityAwardInfo.setPhone(activityTakeInfo.getPhone());
               activityAwardInfo.setGenUserId(activityTakeInfo.getGenUserId());
               activityAwardInfo.setGenUser(activityTakeInfo.getGenUser());
               activityAwardInfo.setGenDept(activityTakeInfo.getGenDept());
               activityAwardInfo.setGenDeptId(activityTakeInfo.getGenDeptId());
               activityAwardInfos.set(i,activityAwardInfo);
           }
           //处理奖品总信息状态
           saveOrUpdate(activityAward);
           //更改奖品明细和活动参与明细表
           iActivityAwardInfoService.saveOrUpdateBatch(activityAwardInfos);
           iActivityTakeInfoService.saveOrUpdateBatch(activityTakeInfoList);
           return activityTakeInfoList;
       }

    }

    @Override
    public List<ActivityTakeInfo> drawAwardGetTake(DrawAwardVo drawAwardVo) {
        List<ActivityTakeInfo> activityTakeInfos =new ArrayList<>();
        ActivityAward activityAward= getOne(new QueryWrapper<ActivityAward>()
                .eq("award_code",drawAwardVo.getAwardCode()));
        if("2".equals(activityAward.getStatus())){
            return activityTakeInfos;
        }
        Random random = new Random();
        Integer num=random.nextInt(100);
        //查询参与活动未中奖的人员
        activityTakeInfos= iActivityTakeInfoService.list(new QueryWrapper<ActivityTakeInfo>()
                .select("name","phone","take_code")
                .eq("status","2")
                .eq("activity_code",activityAward.getActivityCode())
                .groupBy("take_code")
                .last("limit "+num+",60"));
        return activityTakeInfos;
    }
}
